package com.tangr.adapterapplication;

import android.animation.ValueAnimator;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.tangr.normaladapter.recyclerview.RecyclerAdapter;

/**
 * Created by tangr on 16/10/29.
 */

public class CustonPullRecyclerview extends LinearLayout{
    public static final int STATUS_COMPLETE = 0;
    public static final int STATUS_PULL_TO_REFRESH = 1;
    public static final int STATUS_RELEASE_TO_REFRESH = 2;
    public static final int STATUS_REFRESHING = 3;
    private int mCurrentStatus = STATUS_PULL_TO_REFRESH;

    private View headview;
    private ProgressBar progressBar;
    private ImageView arrow;
    private TextView description;
    private TextView updateAt;
    private int touchSlop;
    private RecyclerView recyclerview;
    private boolean loadOnce;
    private int hideHeaderHeight;
    private MarginLayoutParams headerLayoutParams;
    private boolean canPull = true;
    private float mTouchY;
    private int lastStatus;
    private PullToRefreshListener listener;

    public CustonPullRecyclerview(Context context) {
        this(context,null);
    }

    public CustonPullRecyclerview(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    private void initView(Context context) {
        LayoutInflater.from(getContext()).inflate(R.layout.layout_costum_pr,this,true);
        recyclerview = (RecyclerView)findViewById(R.id.recyclerview);
        headview = findViewById(R.id.pull_to_refresh_head);
        progressBar = (ProgressBar) headview.findViewById(R.id.progress_bar);
        arrow = (ImageView) headview.findViewById(R.id.arrow);
        description = (TextView) headview.findViewById(R.id.description);
        updateAt = (TextView) headview.findViewById(R.id.updated_at);
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
                int position = manager.findFirstCompletelyVisibleItemPosition();
                if (position==0)
                    canPull = true;
                else
                    canPull = false;
            }
        });
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed && !loadOnce) {
            hideHeaderHeight = -headview.getHeight();
            headerLayoutParams = (MarginLayoutParams) headview.getLayoutParams();
            headerLayoutParams.topMargin = hideHeaderHeight;
            loadOnce = true;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mTouchY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float dy = event.getY() - mTouchY;
                if (dy > 0 && canPull)
                    return true;
            case MotionEvent.ACTION_UP:
                break;
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float dy = event.getY() - mTouchY;
                mTouchY = event.getY();
                if (Math.abs(mTouchY)<touchSlop)
                    break;
                if (mCurrentStatus != STATUS_REFRESHING) {
                    headerLayoutParams.topMargin += dy / 2;
//                    Log.e("sss","top:"+headerLayoutParams.topMargin);
                    if (headerLayoutParams.topMargin<=hideHeaderHeight){
                        headerLayoutParams.topMargin=hideHeaderHeight;
                        headview.requestLayout();
                        return false;
                    }
                    if (headerLayoutParams.topMargin>=-hideHeaderHeight/3){
                        mCurrentStatus = STATUS_RELEASE_TO_REFRESH;
                    }else {
                        mCurrentStatus = STATUS_PULL_TO_REFRESH;
                    }
                    headview.requestLayout();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mCurrentStatus == STATUS_PULL_TO_REFRESH){
                    headerAnimation(headerLayoutParams.topMargin,hideHeaderHeight,350);
                }else if (mCurrentStatus == STATUS_RELEASE_TO_REFRESH){
                    mCurrentStatus = STATUS_REFRESHING;
                    headerAnimation(headerLayoutParams.topMargin,0,250);
                    if (listener!=null)
                        listener.onRefresh();
                }
                break;
        }
        updateHeaderView();
        lastStatus = mCurrentStatus;
        return super.onTouchEvent(event);
    }

    private void headerAnimation(int start,int end,int time) {
        ValueAnimator animator = ValueAnimator.ofInt(start,end);
        animator.setDuration(time);
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                Log.e("sss",value+"");
                headerLayoutParams.topMargin = value;
                headview.requestLayout();
            }
        });
    }

    private void updateHeaderView() {
        if (lastStatus != mCurrentStatus) {
            if (mCurrentStatus == STATUS_PULL_TO_REFRESH) {
                description.setText("下拉可以刷新");
                arrow.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);
                rotateArrow();
            } else if (mCurrentStatus == STATUS_RELEASE_TO_REFRESH) {
                description.setText("释放立即刷新");
                arrow.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);
                rotateArrow();
            } else if (mCurrentStatus == STATUS_REFRESHING) {
                description.setText("正在刷新。。");
                progressBar.setVisibility(View.VISIBLE);
                arrow.clearAnimation();
                arrow.setVisibility(View.GONE);
            } else if (mCurrentStatus == STATUS_COMPLETE){
                description.setText("更新完成");
                progressBar.setVisibility(View.GONE);
                arrow.clearAnimation();
                arrow.setVisibility(View.GONE);
            }
//            refreshUpdatedAtValue();
        }
    }

    private void rotateArrow() {
        float pivotX = arrow.getWidth() / 2f;
        float pivotY = arrow.getHeight() / 2f;
        float fromDegrees = 0f;
        float toDegrees = 0f;
        if (mCurrentStatus == STATUS_PULL_TO_REFRESH) {
            fromDegrees = 180f;
            toDegrees = 360f;
        } else if (mCurrentStatus == STATUS_RELEASE_TO_REFRESH) {
            fromDegrees = 0f;
            toDegrees = 180f;
        }
        RotateAnimation animation = new RotateAnimation(fromDegrees, toDegrees, pivotX, pivotY);
        animation.setDuration(100);
        animation.setFillAfter(true);
        arrow.startAnimation(animation);
    }

    public void setOnRefreshListener(PullToRefreshListener listener){
        this.listener = listener;
    }

    public void onRefreshComplete(){
        mCurrentStatus = STATUS_COMPLETE;
        updateHeaderView();
        headerAnimation(headerLayoutParams.topMargin,hideHeaderHeight,800);
    }

    public void setLayoutManager(RecyclerView.LayoutManager manager) {
        recyclerview.setLayoutManager(manager);
    }

    public void addItemDecoration(RecyclerView.ItemDecoration decoration) {
        if (decoration != null) {
            recyclerview.addItemDecoration(decoration);
        }
    }

    public void setAdapter(RecyclerAdapter adapter) {
        recyclerview.setAdapter(adapter);
    }

    public interface PullToRefreshListener {
        void onRefresh();
    }
}
